package com.zhoujiang.chapter4.beam;

import com.zhoujiang.chapter4.intercptor.Interceptor;
import com.zhoujiang.chapter4.invoke.Invocation;
import com.zhoujiang.chapter4.service.HelloService;
import com.zhoujiang.chapter4.service.impl.HelloServiceImpl;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyBean implements InvocationHandler {
    private Object target = null;
    private Interceptor interceptor = null;

    /**
     * target被代理对象
     * interceptor拦截器
     *
     * @param target
     * @param interceptor
     * @return
     */
    public static Object getProxyBean(Object target, Interceptor interceptor) {
        ProxyBean proxyBean = new ProxyBean();
        proxyBean.target = target;
        proxyBean.interceptor = interceptor;
        Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), proxyBean);
        return proxy;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        boolean exceptonFlag = false;
        Invocation invocation = new Invocation(args, method, target);
        this.interceptor.before();
        Object retObj = null;
        try {
            if (this.interceptor.useAround()) {
                retObj = this.interceptor.around(invocation);
            } else {
                retObj = method.invoke(target, args);
            }
        } catch (Exception e) {
            exceptonFlag = true;
        }
        this.interceptor.after();
        if (exceptonFlag) {
            this.interceptor.afterThroing();
        } else {
            this.interceptor.afterReturning();
            return retObj;
        }
        return null;
    }
}
